﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include <string>
#include <map>

#include "ExprEngineIntf.h"
#include "ExprTokenType.h"

namespace gcmp
{
    const int EOF_STRING = -1;

    /// \brief 有穷状态机的状态
    enum class StateType : int32_t
    {
        Start = 0,
        InID = 1,
        InIDRef = 2,
        InInteger = 3,
        InFloat = 4,
        InString = 5,
        Done = 6
    };

    /// \brief 词法分析器
    class EXPR_ENGINE_API ExprTokenScanner
    {
    public:
        static std::map<std::wstring, ExprTokenType> s_specialTokenContainer; // And、Or、 Not、 True、 False

    public:
        ExprTokenScanner(IExprEngine* pExprEngine);
        ~ExprTokenScanner() {};

        void SetInputString(wchar_t* pInputStr);
        // 词法分析的主要函数
        ExprTokenType GetToken();
        const wchar_t* GetTokenString();
        std::wstring GetRefIDTokenString() const;
        const int GetCurrentTokenStartPosition() const;
        const int GetCurrentTokenEndPosition() const;

    private:
        int GetNextChar();
        void UngetNextChar();
        ExprTokenType FindSpecialToken(wchar_t* pTokenString);
        void TrimTokenString();

    private:
        wchar_t* m_inputStr;
        int m_position;
        int m_length;
        std::vector<wchar_t> m_tokenStr; // 用于存放关键字的字符串值
        IExprEngine* m_pEngine;
    };
}
